//////////////////////////////////////////////////////////////////////////////////////////////////////
// 项目名   : ConditionVariable
// 文件名   : IBuffer.h
// 作者     : Aiye
// 日期     : 2025/9/23 09:42
// 邮箱     : 2878548868@qq.com
// 摘要     : 
//////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CONDITIONVARIABLE_IBUFFER_H
#define CONDITIONVARIABLE_IBUFFER_H
#include <condition_variable>
#include <mutex>
#include <queue>
#include <iostream>
#include <thread>


class IBuffer
{
public:
    virtual void produce(int nValue) = 0;
    virtual int consume() = 0;
    virtual ~IBuffer() = default;
};

class Buffer final : public IBuffer
{
public:
    void produce(const int nValue) override
    {
        std::unique_lock lock{_mutex};
        _cvProduce.wait(lock , [this]()
        {
           return _buffer.size() < _nMaxSize;
        }); // 当缓存区已满时，生产者等待
        _buffer.push(nValue); // 放入数据
        std::cout << "[" << std::this_thread::get_id() << "] 生产: " << nValue << std::endl;
        _cvConsume.notify_one(); // 通知消费者有数据更新
    }

    int consume() override
    {
        std::unique_lock lock{_mutex};
        _cvConsume.wait(lock , [this]()
        {
            return !_buffer.empty();
        }); // 当缓存区为空时消费者等待
        auto value  = _buffer.front();
        _buffer.pop();
        std::cout << "消费者[" << std::this_thread::get_id() << "] 消费: " << value << std::endl;
        _cvProduce.notify_one();
        return value;

    }
private:
    std::queue<int> _buffer{}; // 缓冲队列
    std::mutex _mutex{};  // 互斥锁
    std::condition_variable _cvProduce{}; // 生产者条件变量
    std::condition_variable _cvConsume{}; // 消费者条件变量
    const size_t _nMaxSize{10}; // 最大数量
};

class Producer
{
public:
    explicit Producer(IBuffer& buf) : _buf(buf) {}
    void run(int nCount)
{
        for (int i = 0; i < nCount; ++i)
        {
            _buf.produce(i);
        }
    }
private:
    IBuffer& _buf;
};

// Consumer.h
#include "IBuffer.h"
class Consumer {
public:
    explicit Consumer(IBuffer& buf) : _buf(buf) {}
    void run(int nCount)
    {
        for (int i = 0; i < nCount; ++i)
        {
            _buf.consume();
        }
    }
private:
    IBuffer& _buf;
};

#endif //CONDITIONVARIABLE_IBUFFER_H